home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / stfight.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  6KB  |  260 lines

  1. /***************************************************************************
  2.  
  3.   machine.c
  4.  
  5.   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
  6.   I/O ports)
  7.  
  8. ***************************************************************************/
  9.  
  10. #include "driver.h"
  11. #include "vidhrdw/generic.h"
  12. #include "cpu/z80/z80.h"
  13.  
  14. // this prototype will move to the driver
  15. WRITE_HANDLER( stfight_bank_w );
  16.  
  17.  
  18. /*
  19.  
  20. Encryption PAL 16R4 on CPU board
  21.  
  22.           +---U---+
  23.      CP --|       |-- VCC
  24.  ROM D1 --|       |-- ROM D0          M1 = 0                M1 = 1
  25.  ROM D3 --|       |-- (NC)
  26.  ROM D4 --|       |-- D6         D6 = D1 ^^ D3          D6 = / ( D1 ^^ D0 )
  27.  ROM D6 --|       |-- D4         D4 = / ( D6 ^^ A7 )    D4 = D3 ^^ A0
  28.      A0 --|       |-- D3         D3 = / ( D0 ^^ A1 )    D3 = D4 ^^ A4
  29.      A1 --|       |-- D0         D0 = D1 ^^ D4          D0 = / ( D6 ^^ A0 )
  30.      A4 --|       |-- (NC)
  31.      A7 --|       |-- /M1
  32.     GND --|       |-- /OE
  33.           +-------+
  34.  
  35. */
  36.  
  37. void init_empcity(void)
  38. {
  39.     unsigned char *rom = memory_region(REGION_CPU1);
  40.     int diff = memory_region_length(REGION_CPU1) / 2;
  41.     int A;
  42.  
  43.  
  44.     memory_set_opcode_base(0,rom+diff);
  45.  
  46.     for (A = 0;A < 0x8000;A++)
  47.     {
  48.         unsigned char src = rom[A];
  49.  
  50.         // decode opcode
  51.         rom[A+diff] =
  52.                 ( src & 0xA6 ) |
  53.                 ( ( ( ( src << 2 ) ^ src ) << 3 ) & 0x40 ) |
  54.                 ( ~( ( src ^ ( A >> 1 ) ) >> 2 ) & 0x10 ) |
  55.                 ( ~( ( ( src << 1 ) ^ A ) << 2 ) & 0x08 ) |
  56.                 ( ( ( src ^ ( src >> 3 ) ) >> 1 ) & 0x01 );
  57.  
  58.         // decode operand
  59.         rom[A] =
  60.                 ( src & 0xA6 ) |
  61.                 ( ~( ( src ^ ( src << 1 ) ) << 5 ) & 0x40 ) |
  62.                 ( ( ( src ^ ( A << 3 ) ) << 1 ) & 0x10 ) |
  63.                 ( ( ( src ^ A ) >> 1 ) & 0x08 ) |
  64.                 ( ~( ( src >> 6 ) ^ A ) & 0x01 );
  65.     }
  66. }
  67.  
  68. void init_stfight(void)
  69. {
  70.     unsigned char *rom = memory_region(REGION_CPU1);
  71.     int diff = memory_region_length(REGION_CPU1) / 2;
  72.  
  73.  
  74.     init_empcity();
  75.  
  76.     /* patch out a tight loop during startup - is the code waiting */
  77.     /* for NMI to wake it up? */
  78.     rom[0xb1 + diff] = 0x00;
  79.     rom[0xb2 + diff] = 0x00;
  80.     rom[0xb3 + diff] = 0x00;
  81.     rom[0xb4 + diff] = 0x00;
  82.     rom[0xb5 + diff] = 0x00;
  83. }
  84.  
  85. void stfight_init_machine( void )
  86. {
  87.     // initialise rom bank
  88.     stfight_bank_w( 0, 0 );
  89. }
  90.  
  91. // It's entirely possible that this bank is never switched out
  92. // - in fact I don't even know how/where it's switched in!
  93. WRITE_HANDLER( stfight_bank_w )
  94. {
  95.     unsigned char   *ROM2 = memory_region(REGION_CPU1) + 0x10000;
  96.  
  97.     cpu_setbank( 1, &ROM2[data<<14] );
  98. }
  99.  
  100. int stfight_vb_interrupt( void )
  101. {
  102.     // Do a RST10
  103.     interrupt_vector_w( 0, 0xd7 );
  104.  
  105.     return( interrupt() );
  106. }
  107.  
  108. /*
  109.  *      CPU 1 timed interrupt - 30Hz???
  110.  */
  111.  
  112. int stfight_interrupt_1( void )
  113. {
  114.     // Do a RST08
  115.     interrupt_vector_w( 0, 0xcf );
  116.  
  117.     return( interrupt() );
  118. }
  119.  
  120. /*
  121.  *      CPU 2 timed interrupt - 120Hz
  122.  */
  123.  
  124. int stfight_interrupt_2( void )
  125. {
  126.     return( interrupt() );
  127. }
  128.  
  129. /*
  130.  *      Hardware handlers
  131.  */
  132.  
  133. // Perhaps define dipswitches as active low?
  134. READ_HANDLER( stfight_dsw_r )
  135. {
  136.     return( ~readinputport( 3+offset ) );
  137. }
  138.  
  139. static int stfight_coin_mech_query_active = 0;
  140. static int stfight_coin_mech_query;
  141.  
  142. READ_HANDLER( stfight_coin_r )
  143. {
  144.     static int coin_mech_latch[2] = { 0x02, 0x01 };
  145.  
  146.     int coin_mech_data;
  147.     int i;
  148.  
  149.     // Was the coin mech queried by software?
  150.     if( stfight_coin_mech_query_active )
  151.     {
  152.         stfight_coin_mech_query_active = 0;
  153.         return( (~stfight_coin_mech_query) & 0x03 );
  154.     }
  155.  
  156.     /*
  157.      *      Is this really necessary?
  158.      *      - we can control impulse length so that the port is
  159.      *        never strobed twice within the impulse period
  160.      *        since it's read by the 30Hz interrupt ISR
  161.      */
  162.  
  163.     coin_mech_data = readinputport( 5 );
  164.  
  165.     for( i=0; i<2; i++ )
  166.     {
  167.         /* Only valid on signal edge */
  168.         if( ( coin_mech_data & (1<<i) ) != coin_mech_latch[i] )
  169.             coin_mech_latch[i] = coin_mech_data & (1<<i);
  170.         else
  171.             coin_mech_data |= coin_mech_data & (1<<i);
  172.     }
  173.  
  174.     return( coin_mech_data );
  175. }
  176.  
  177. WRITE_HANDLER( stfight_coin_w )
  178. {
  179.     // interrogate coin mech
  180.     stfight_coin_mech_query_active = 1;
  181.     stfight_coin_mech_query = data;
  182. }
  183.  
  184. /*
  185.  *      Machine hardware for MSM5205 ADPCM sound control
  186.  */
  187.  
  188. static int sampleLimits[] =
  189. {
  190.     0x0000,     // machine gun fire?
  191.     0x1000,     // player getting shot
  192.     0x2C00,     // player shooting
  193.     0x3C00,     // girl screaming
  194.     0x5400,     // girl getting shot
  195.     0x7200      // (end of samples)
  196. };
  197. static int adpcm_data_offs;
  198. static int adpcm_data_end;
  199.  
  200. void stfight_adpcm_int( int data )
  201. {
  202.     static int toggle;
  203.     unsigned char *SAMPLES = memory_region(REGION_SOUND1);
  204.     int adpcm_data = SAMPLES[adpcm_data_offs & 0x7fff];
  205.  
  206.     // finished playing sample?
  207.     if( adpcm_data_offs == adpcm_data_end )
  208.     {
  209.         MSM5205_reset_w( 0, 1 );
  210.         return;
  211.     }
  212.  
  213.     if( toggle == 0 )
  214.         MSM5205_data_w( 0, ( adpcm_data >> 4 ) & 0x0f );
  215.     else
  216.     {
  217.         MSM5205_data_w( 0, adpcm_data & 0x0f );
  218.         adpcm_data_offs++;
  219.     }
  220.  
  221.     toggle ^= 1;
  222. }
  223.  
  224. WRITE_HANDLER( stfight_adpcm_control_w )
  225. {
  226.     if( data < 0x08 )
  227.     {
  228.         adpcm_data_offs = sampleLimits[data];
  229.         adpcm_data_end = sampleLimits[data+1];
  230.     }
  231.  
  232.     MSM5205_reset_w( 0, data & 0x08 ? 1 : 0 );
  233. }
  234.  
  235. WRITE_HANDLER( stfight_e800_w )
  236. {
  237. }
  238.  
  239. /*
  240.  *      Machine hardware for YM2303 fm sound control
  241.  */
  242.  
  243. static unsigned char fm_data;
  244.  
  245. WRITE_HANDLER( stfight_fm_w )
  246. {
  247.     // the sound cpu ignores any fm data without bit 7 set
  248.     fm_data = 0x80 | data;
  249. }
  250.  
  251. READ_HANDLER( stfight_fm_r )
  252. {
  253.     int data = fm_data;
  254.  
  255.     // clear the latch?!?
  256.     fm_data &= 0x7f;
  257.  
  258.     return( data );
  259. }
  260.